<?php

namespace App\Service\Third;

use App\Helpers\PayUtil;
use App\Helpers\RedisUtil;
use App\Model\PaycallbackLog;
use App\Model\PayOrder;
use App\Model\Service\PaycallbackService;

/**
 * 支付宝支付回调
 */
class AliPayCallbackService extends PayBaseService
{
    public function handle()
    {
        $callbackArray = $this->request->all();
        // return ['result' => 1];
        $outTradeNo = $this->parseOutTradeNo($callbackArray);

        if ($callbackArray['trade_status'] && $callbackArray['trade_status'] != 'TRADE_SUCCESS') {
            log_info(__CLASS__ . "==TradeStatus:{$callbackArray['trade_status']}=={$outTradeNo}");
            return ['result' => 1];
        }

        //记录请求日志
        PaycallbackLog::addRecord(PayOrder::CHANNEL_ALI, $outTradeNo, $callbackArray);

        // $blackIps = []; //'203.209.246'
        // if ($callbackArray['client_ip'] && in_array(substr($callbackArray['client_ip'], 0, 11), $blackIps)) {
        //     log_info(__CLASS__ . "==BlackIp=={$outTradeNo}=={$callbackArray['client_ip']}");
        //     return ['result' => 1];
        // }
        //锁住
        $lockTime = 120;
        $key = "AliPayCallbackService_{$outTradeNo}";
        if (RedisUtil::concurrentLock($key, $lockTime)) {
            log_info(__CLASS__ . "==LastProcessing=={$outTradeNo}");
            return ['result' => 1];
        }

        // SDK实例化，传入公共配置
        $appKey = PayUtil::aliAppkeyByAppId($callbackArray['auth_app_id']);
        $paySdk = new \Yurun\PaySDK\AlipayApp\SDK(PayUtil::alipayPublicParams($appKey));
        $verify = $paySdk->verifyCallback($callbackArray);
        if ($verify) {
            // 通知验证成功
            log_info(__CLASS__ . "==Success=={$outTradeNo}");
            //支付回调
            $payMoney = $this->parsePayMoney($callbackArray);
            PaycallbackService::successCallback($outTradeNo, $payMoney, PayOrder::CHANNEL_ALI);
        } else {
            // 通知验证失败
            log_info(__CLASS__ . "==Fail=={$outTradeNo}==");
        }
        return ['result' => 1];
    }

    /**
     * 解析支付订单号
     */
    protected function parseOutTradeNo($callbackArray = [])
    {
        return $callbackArray['out_trade_no'] ?? '';
    }

    /**
     * 解析支付总金额（分）
     */
    protected function parsePayMoney($callbackArray = [])
    {
        return isset($callbackArray['total_amount']) ? $callbackArray['total_amount'] * 100 : 0;
    }
}
